Release 10.1A: OpenEdge Development:
Progress 4GL Handbook


Global shared objects in Progress

There’s another variation on the shared object theme, and this is global shared objects. The first procedure to define an object includes the GLOBAL keyword in the definition:

DEFINE [ [ NEW [ GLOBAL ] ] SHARED ] VARIABLE cString AS CHARACTER NO-UNDO 

This makes the object definition available to the entire session. The same set of objects that can be defined as NEW SHARED can also be defined as NEW GLOBAL SHARED. For example, one procedure can have this global definition:

DEFINE NEW GLOBAL SHARED VARIABLE cEverywhere AS CHARACTER NO-UNDO. 

Any other procedure in the Progress session that is executed after that procedure can have this definition and make use of the same variable:

DEFINE SHARED VARIABLE cEverywhere AS CHARACTER NO-UNDO. 

One tricky aspect to this is the after that procedure requirement. In many applications, it is not easy to determine which of the procedures that might want to reference a value will execute first, and therefore should be the procedure that defines it. Or you might have many procedures that need to reference the value and not know which of them will execute at all in the course of a session.

Progress provides a work-around for this problem. If a procedure defines an object as NEW GLOBAL SHARED and another procedure has already registered this definition, then no error results. Progress ignores the NEW GLOBAL part of the second definition and accepts it as a reference to the existing SHARED object. This is different from nonglobal shared objects, where a second NEW SHARED reference causes a run-time error.

For this reason, it is common practice simply to use the NEW GLOBAL SHARED syntax in every procedure that needs to use the objects. Although this is somewhat contradictory to the way the nonglobal shared syntax works, it is reliable behavior.

When to consider using global shared objects

You might think that global shared objects are a better way to go in new applications than nonglobal shared objects, because multiple procedures that aren’t necessarily running in a single predictable procedure call stack can all access them. Also, any of the procedures can define them first and others can define them and use them in any order. Thus, you could place a set of global definitions into an include file and include it in every procedure that needs them, without regard for which procedure has to use the NEW keyword in its definitions.

Up to a point this is correct, but there are good reasons why you should generally avoid global shared objects in new applications:

  1. Simply having an include file that many procedures depend on is poor practice in a modern application. Any time the list of definitions in this file changes for any reason, every procedure that uses it must be recompiled and potentially redeployed. As you learn more about dynamic language constructs in later chapters, you learn useful alternatives to global shared variables that are more flexible and can change at run time without any code changes or recompilation at all.
  2. Global shared objects create potential namespace conflicts and possible unintended consequences in your application, precisely because they are global. A global shared object is visible to every procedure in the entire session, and every procedure shares that name and its value. Global shared objects never go out of scope and they can’t be deleted. They exist from the time the first definition is encountered until the session ends. An important aspect of a modern application is that it is as modular as possible, with code and data for a particular module isolated within a set of procedures that can run independently of other modules. What happens when two modules happen to use the same name for a global object? The result is that Progress defines just one object, with a single value, and two different sets of code are trying to use it for different purposes. Very insidious errors can result.

Thus, it’s generally advisable that you should avoid global objects wherever possible. If you do think you want to use them, consider these important guidelines:

In the following chapter, you’ll learn about a newer language construct that very definitely is of great use, your own 4GL functions, which you can often use as an alternative to internal procedures.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095